<template>
  <div id="SmTable">
    <!-- v-bind="$attrs" style="height:calc(100vh - 285px)"-->

    <el-table
      ref="tableRef"
      v-loading="loading"
      :stripe="stripe"
      :showOverflowTooltip="showOverflowTooltip"
      :data="tableData"
      :border="border"
      v-bind="TableAttrs()"
      @row-click="rowClick"
      class="SmTable-el-table"
      :max-height="maxHeight"
      @selection-change="handleSelectionChange"
    >
      <el-table-column
        v-if="isSelection"
        fixed="left"
        width="40"
        label="选择"
        type="selection"
        :reserve-selection="reserveSelection"
        align="center"
      />

      <el-table-column v-if="oneSelection" fixed="left" align="center" width="40">
        <template #default="scope">
          <el-radio
            :value="scope.row.id"
            v-model="currentRowValue"
            @change="handleCurrentChange(scope.row)"
          />
        </template>
      </el-table-column>
      <el-table-column
        v-if="isIndex"
        fixed="left"
        label="序号"
        type="index"
        align="center"
        width="60"
      />
      <!-- 后期可以补充oneSelectionAttrs进行扩展 -->

      <template v-for="(item, index) in tableOption" :key="item.prop">
        <el-table-column
          v-if="item.prop && !item.action"
          :label="item.label"
          :prop="item.prop"
          :width="item.width"
          :align="item.align"
          :formatter="item.formatter"
          :min-width="item['min-width']"
          v-bind="columnItem(item)"
        >
          <template v-if="item.slot" #default="scope">
            <template v-if="scope.row.rowEdit">
              <el-input v-model="scope.row[item.prop!]" size="small" />
            </template>

            <template v-else-if="item.textMap">
              {{ item.textMap[scope.row[item.prop!]] }}
            </template>

            <template v-else-if="item.dictAttrs">
              <DictLabel v-model="scope.row[item.prop]" :code="item.dictAttrs.type" size="small" />
              <!-- <dict-tag :type="item.dictAttrs.type" :value="scope.row[item.prop] ?? ''" /> -->
            </template>

            <template v-else-if="item.imageAttrs">
              <el-image
                :src="scope.row[item.prop]"
                class="w-64px h-64px"
                v-bind="item.imageAttrs"
              />
            </template>

            <template v-else-if="item.wrap">
              <div :class="['slot-wrap', `slot-${item.prop}`]">{{ scope.row[item.prop!] }}</div>
            </template>

            <template v-else>
              <template v-if="scope.$index + scope.column.id === currentEdit">
                <div style="display: flex">
                  <el-input v-model="scope.row[item.prop!]" size="small" />
                  <div>
                    <slot v-if="$slots.cellEdit" name="cellEdit" :scope="scope"></slot>
                    <div v-else class="action-icon">
                      <el-icon-check class="check" @click.stop="check(scope)" />
                      <el-icon-close class="close" @click.stop="close(scope)" />
                    </div>
                  </div>
                </div>
              </template>
              <template v-else>
                <!-- eslint-disable vue/valid-attribute-name -->
                <slot
                  v-if="item.slot && scope.$index >= 0"
                  :name="item.slot"
                  :scope="scope"
                  :row="scope.row"
                  :$index="scope.$index"
                ></slot>
                <!-- <span v-else>{{ scope.row[item.prop!] }}</span> -->
                <!-- <component
                  :is="`el-icon-${toLine(editIcon)}`"
                  v-if="item.editable"
                  class="edit"
                  @click.stop="clickEditIcon(scope)"
                /> -->
              </template>
            </template>
          </template>
        </el-table-column>
      </template>
      <!-- <el-table-column
        v-if="actionOption"
        :label="actionOption.label"
        :width="actionOption.width"
        :align="actionOption.align"
        :formatter="actionOption.formatter"
        :min-width="actionOption['min-width']"
        v-bind="columnItem(actionOption)"
      >
        <template #default="scope">
          <slot v-if="scope.row.rowEdit" name="editRow" :scope="scope"></slot>
          <slot v-else name="action" :scope="scope"></slot>
        </template>
      </el-table-column> -->
    </el-table>

    <Pagination class="SmTable-Pagination" v-if="pagination && !loading" v-bind="pageAttrs()" />
  </div>
</template>

<script lang="ts" setup>
import { PropType, computed, ref, watch, onMounted } from "vue";
import Pagination from "./components/Pagination.vue";
import TableList from "./components/TableList.vue";

import { TableOptions } from "./types";
import { toLine } from "./utils";
import { cloneDeep } from "lodash-es";
import { createDBFn } from "@/utils/decorate";
import { useFixedTable } from "./hooks";

/** 基础列表 */
defineOptions({ name: "SmTable" });

/** 分页参数需要手动添加和表格参数做区分 */
const pageAttrs = () => {
  const pageAttrs = useAttrs() || {};
  const pageProps = [
    "pageSize",
    "currentPage",
    "onPagination",
    "onUpdate:currentPage",
    "onUpdate:pageSize",
    "pageSize",
    "total",
  ];
  const obj: any = { total: 0 };
  pageProps.forEach((item) => {
    obj[item] = pageAttrs[item];
  });
  // console.log(pageAttrs, 'useAttrs-useAttrs')
  return obj;
  // return Object.assign({ total: 0 }, pageAttrs)
};

const TableAttrs = () => {
  const attrs = useAttrs() || {};
  const obj: any = {};
  const filterAttrs = ["style"];
  for (let key in attrs) {
    if (!filterAttrs.includes(key)) {
      obj[key] = attrs[key];
    }
  }
  return obj;
};

// 事件字段都要在这里统一添加
const tableFieldAttrs = () => {
  const attrs = useAttrs() || {};
  const obj: any = {};
  const filterAttrs = [
    "tableFieldMap",
    "tableFieldOptions",
    "tableFieldKey",
    "iconSize",
    "isWholeOrder",
    "wholeOrderEnable",
    "onTableFieldConfirm",
  ];
  for (let key in attrs) {
    if (filterAttrs.includes(key)) {
      obj[key] = attrs[key];
    }
  }
  return obj;
};

const columnItem = (item) => {
  const list = ["label", "prop", "width", "align", "formatter"];
  const filterItem = {};
  for (const key in item) {
    if (!list.includes(key)) {
      filterItem[key] = item[key];
    }
  }
  return filterItem;
};

const props = defineProps({
  reserveSelection: {
    type: Boolean,
    default: false,
  },
  // 是否开启单选
  oneSelection: {
    type: Boolean,
    default: false,
  },
  // 是否开启选择列
  isSelection: {
    type: Boolean,
    default: false,
  },
  // 是否开启序号
  isIndex: {
    type: Boolean,
    default: false,
  },
  // 是否在加载中
  loading: {
    type: Boolean,
    default: false,
  },
  // 表格配置选项
  options: {
    type: Array as PropType<TableOptions[]>,
    required: true,
  },
  // 表格数据
  data: {
    type: Array,
    required: true,
  },
  getTableData: {
    type: Function,
    default: null,
  },
  // 是否开启
  border: {
    type: Boolean,
    default: true,
  },
  // 是否为斑马纹
  stripe: {
    type: Boolean,
    default: true,
  },
  // 是否隐藏额外内容并在单元格悬停时使用 Tooltip 显示它
  showOverflowTooltip: {
    type: Boolean,
    default: false,
  },
  // 编辑显示的图标
  editIcon: {
    type: String,
    default: "Edit",
  },
  // 是否可以编辑行
  isEditRow: {
    type: Boolean,
    default: false,
  },
  // 编辑行按钮的标识
  editRowType: {
    type: String,
    default: "",
  },
  // 是否显示分页
  pagination: {
    type: Boolean,
    default: true,
  },
  // 是否开启表格设置齿轮
  isTabledField: {
    type: Boolean,
    default: false,
  },
  // 是否开启表格高度固定
  isTableHeight: {
    type: Boolean,
    default: false,
  },
});

const emits = defineEmits([
  "confirm",
  "cancel",
  "update:editRowType",
  "row-click",
  "oneSelectionChange",
  "update:data",
  "selection-change",
]);

// 当前被点击的单元格的标识
const currentEdit = ref<string>("");

// 拷贝一份表格的数据
const tableData = ref<any[]>([]);

watch(
  () => props.data,
  (val) => {
    if (val?.length) {
      // tableData.value = cloneDeep(val).map((item: any) => {
      //   item.rowEdit = false
      //   return item
      // })
      tableData.value = val;
    } else {
      tableData.value = [];
    }
  },
  { immediate: true, deep: true }
);

watch(
  () => tableData.value,
  (val) => {
    // if (props.getTableData) {
    //   const outTableData = props.getTableData()
    //   if (val?.length) {
    //     // 更新每个项的数据
    //     val.forEach((item, index) => {
    //       Object.assign(unref(outTableData)[index], item)
    //     })
    //   } else {
    //     outTableData.value = []
    //   }
    // }
  },
  { immediate: true, deep: true }
);

// 过滤操作项之后的配置
const tableOption = computed(() => props.options.filter((item) => !item.action));
// 操作项
// const actionOption = computed(() => props.options.find((item) => item.action));

// 点击编辑图标
const clickEditIcon = (scope: any) => {
  // 会做一个判断 判断是否当前单元格被点击了
  // 拼接$index和column的id
  currentEdit.value = scope.$index + scope.column.id;
};

// 点击确认
const check = (scope: any) => {
  emits("confirm", scope);
  currentEdit.value = "";
};
// 点击取消
const close = (scope: any) => {
  emits("cancel", scope);
  currentEdit.value = "";
};

// 点击行的事件
const rowClick = (row: any, column: any) => {
  emits("row-click", row, column);
  // // 判断是否是点击的操作项
  // const clickOperate =
  //   column.label === actionOption.value!.label && props.isEditRow && props.editRowType === 'edit'
  // //&& cloneeditRowType.value === props.editRowType

  // if (clickOperate) {
  //   // 编辑行的操作
  //   row.rowEdit = !row.rowEdit
  //   // 重置其他数据的rowEdit
  //   tableData.value.map((item) => {
  //     if (item !== row) item.rowEdit = false
  //   })

  //   // 重置按钮的标识
  //   if (!row.rowEdit) emits('update:editRowType', '')
  // }
};

/** 选中行 */
const currentRowValue = ref(undefined); // 选中行的 value
const currentRow = ref(undefined); // 选中行
const handleCurrentChange = (row) => {
  currentRow.value = row;
  emits("oneSelectionChange", row);
};

const selectionList = ref([]);
const handleSelectionChange = (rows) => {
  selectionList.value = rows;
  emits("selection-change", rows);
};

const tableListDialog = ref(false);

const tableRef = ref();
const { maxHeight, updateScrollTopDB } = useFixedTable();

// onMounted(() => {
//   const scrollDom = window?.layoutScrollbarRef?.value?.wrapRef;
//   if (props.isTableHeight && scrollDom) {
//     scrollDom.addEventListener("scroll", updateScrollTopDB);
//   }
// });

// onUnmounted(() => {
//   const scrollDom = window?.layoutScrollbarRef?.value?.wrapRef;
//   if (props.isTableHeight && scrollDom) {
//     scrollDom.removeEventListener("scroll", updateScrollTopDB);
//   }
// });
defineExpose({ tableRef }); // 提供 open 方法，用于打开弹窗
</script>

<style lang="scss" scoped>
.btn-list {
  display: flex;
  align-items: center;
  margin-bottom: 5px;
}

.edit {
  position: relative;
  top: 2px;
  left: 12px;
  width: 1em;
  height: 1em;
  cursor: pointer;
}

.action-icon {
  display: flex;

  svg {
    position: relative;
    top: 8px;
    width: 1em;
    height: 1em;
    margin-left: 8px;
    cursor: pointer;
  }

  .check {
    color: red;
  }

  .close {
    color: green;
  }
}
.slot-wrap {
  white-space: normal;
}
#SmTable {
  display: flex;
  flex-direction: column;
}
.SmTable-el-table {
  flex: 1;
}
.SmTable-Pagination {
  display: flex;
  justify-content: flex-end;
  align-items: center;
}
// :global(#SmTable .cell) {
//   padding: 0!important;
// }
</style>
